GO
这些内容是在学习Shell脚本之前必须要掌握的Shell基础知识。
Shell 初相识
什么是Shell
Shell 是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具。在Shell和计算机硬件中间还有一层东西,那就是系统内核。用户在使用计算机的时候,直接面对的并不是计算机硬件,而是Shell,用户把指令告诉Shell,然后Shell再传输给系统内核,接着内核再去支配计算机硬件去执行各种操作。
Shell的版本有很多,但是初学时所接触的Linux发布版本(RedHat或CentOS系列)默认安装的Shell版本是bash(即Bourne Again Shell),它是sh(Bourne Shell)的增强版本。Bourne Shell是最早流行起来的一个Shell版本。其创始人是Steven Bourne,为了纪念他而将其命名为Bourne Shell,简称sh。
Shell的特性
命令记录历史
history
history
:用来查看命令历史列表。
- 我们执行过的命令bash都会记录,预设可以记录1000条历史命令,这些命令保存在用户的家目录下的
.bash_history
文件中。 - 需要注意的是,只有当用户正常退出当前Shell时,在当前Shell中运行过的命令才会保存至该文件里。
- 我们可以自定义命令历史的大小,可以更改在配置文件/etc/profile 中的 HISTSIZE 环境变量。比如我们可以将其更改为2000。
- 我们也可以设置一下命令历史的记录格式,比如在每条命令前加上其被执行的时间,这时我们应该设置 HISTTIMEFORMAT 环境变量,也是在配置文件 /etc/profile 中进行设置,为了方便查看,可以在 HISTSIZE 下面增加一条:
HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S"
。 - 我们可以把记录命令历史的文件设置成永久保存的权限,即不允许删除其内容,只能追加:
chattr +a ~/.bash_history
。 - Ctrl+r:可以搜索命令历史来执行
关于!的几个用法
!
是与命令历史有关的一个特殊字符,该字符常用的应用有一下几个:
!!
:连续两个!表示执行上一条命令。!n
:这里的n是数字,表示执行命令历史中的第n条命令。可用命令history
查看历史命令列表。!字符串(字符串大于等于1)
:执行最近一次以该字符串开头的命令!$
:使用上一次命令的最后一个参数
命令和文件名补全
Tab
按键可以补全命令、补全路径或者一个文件名。连续按两次该键会把所有命令或文件名都显示出来。
- 命令补全
- 目录补全和文件名补全
- 命令参数补全 (默认不支持,需要安装一个包:
yum install -y bash-comletion
,安装后重启系统即可生效)
别名
alias 设置别名
格式 alias 别名字符串='所要替代的指令和该指令的参数'
直接执行 alias
会把目前系统预设的别名全部列出来。
别名的配置文件有:~/.bashrc 、 /etc/profile.d/下的脚本里
每个用户可以在自己的配置文件 ~/.bashrc 中加入自定义的别名。
unalias 取消别名
格式 unalias 别名字符串
通配符
在bash下、可以使用*来匹配零个或多个字符,用?匹配一个字符,[]匹配里面的任一个字符(如 [0-9]),{}表示任取一组。
输入/输出重定向
符号 | 意义 |
---|---|
> | 输出重定向 |
>> | 输出追加重定向 |
< | 输入重定向(例子:mail -s "zhuti" somebody@host.com < 邮件内容文件.txt ) |
2> | 错误输出重定向 |
2>> | 错误输出追加重定向 |
2>&1 | 相当于 > 1.txt 2> 1.txt |
2>>&1 | 相当于 >> 1.txt 2>> 1.txt |
&> | 把错误和正确的信息重定向到一个文件 |
&>> | 把错误和正确的信息追加重定向到一个文件 |
管道符
管道符|
,它用于将前一个指令的标准输出作为后一个指令的参数。
作业控制
当运行程序时,可以使它暂停(按Ctrl+Z组合键),然后使用fg(foreground的简写)命令恢复它,或是用bg(background的简写)命令使它到后台运行(或是在运行命令的时候在命令后面加一个&符号)。此外,还可以使它终止运行(按Ctrl+C组合键)。
多个被暂停的任务会有编号,使用jobs命令可以查看到放在后台的任务列表以及它们的编号,ID号后面有+ 或 - ,表示优先级。+比-优先级高。在这时使用bg或者fg命令时,则需要在后面加上编号。若不加编号,默认恢复优先级高的。
如何关掉在后台运行的任务呢?这分两种情况:
- 如果你没有退出Shell,则应先使用
fg 编号
把任务调到前台,然后按Ctrl+C组合键结束任务。 - 关闭了当前Shell,再次打开另一个Shell时,使用jobs命令并不会显示在后台运行或者被暂停的任务。要想关闭这些任务,则需要先知道它们的PID。用这个命令
ps aux | grep 关键字
找到这个进程。若是想结束这个进程,需要使用到kill命令。
kill命令很简单,直接在后面加PID即可 kill PID
。如果遇到结束不了的进程时,可以在Kill后面加一个选项,即 kill -9 PID
。
总结:
命令 | 意义 |
---|---|
Ctrl+Z | 暂停任务 |
fg [编号] | 继续任务,把任务调到前台 |
bg [编号] | 把命令调到后台并运行 |
命令 & | 把命令直接丢到后台并运行 |
jobs | 查看进程列表和编号 |
Ctrl+C | 结束当前任务 |
ps aux | 查看相关进程的PID |
kill [-9] PID | 结束进程 |
变量
在Linux系统中预设了很多变量,可以供我们使用。我们也可以自定义一些变量,包括局部变量和全局变量。
echo $变量名
echo $变量名
用于查看一个变量的值。
env
env
用于查看系统的全部环境变量。
登陆不同的用户,这些环境变量的值也不同。常见的环境变量如下:
变量名 | 值的意义 |
---|---|
HOSTNAME | 主机名 |
SHELL | 当前用户的Shell类型 |
HISTSIZE | 命令历史记录数 |
当前用户的邮件存放目录 | |
PATH | 该变量决定了Shell将到哪些目录中寻找命令或程序 |
PWD | 当前目录 |
LANG | 这是与语言相关的环境变量,多语言环境可以修改此环境变量 |
HOME | 当前用户的家目录 |
LOGNAME | 当前用户的登陆名 |
注意:env命令显示的变量只是环境变量,系统预设的变量其实还有很多,这就需要用到下面的set命令了。
还有两个变需要了解一下:
- PS1:shell中的提示符
- PS2:当在shell中执行换行后再继续操作时的提示符
set 和 unset
set
用于查看系统里的全部变量,包括环境变量和用户自定义变量。unset 变量名
可取消或删除一个变量
export 变量名
export 变量名
声明一个变量为全局变量。
自定义变量
定义变量的方式
变量=值
只能在当前Shell中使用,不能在子Shell中使用。export 变量=值
设置了一个全局变量,可以在当前Shell和子Shell中使用。
自定义变量的规则
- 设定变量的格式为
a=b
,其中a为变量名,b为变量的值,等号两边不能有空格。 - 变量名只能由字母、数字以及下划线组成,且不能以数字开头。
- 当变量内容带有特殊字符时,需要进行特殊处理,如下:
- 当变量内容带有空格时,需要给该变量加上单引号。如 myname=’Aming Linux’
- 当变量内容带有单引号,需要给该变量加上双引号。如 myname=”I’m a cocker”
- 若变量内容中需要用到其它命令,只使用该命令的运行结果作为变量的值,则该命令需要加上反引号。如 myname=`pwd`
- 变量内容可以累加其它变量的内容,但需要加双引号。如 myname=”$LOGNAME”Aming
- b=$a”123” 或 b=$a’123’
- c=$a$b
- a=$a”增加值”
- 注意单引号、双引号和反引号的使用区别:
- 单引号:里面的内容全部是普通字符
- 双引号:里面的内容带有本身的意义,比如某个变量
- 反引号:里面的内容为一个命名,所代表的是该命令执行之后的结果
让自定义变量一直生效
如果想要使自定义的变量一直生效,该如何办到呢?分以下两种情况:
- 允许系统内所有用户登陆后都可以使用该变量。
- 在/etc/profile文件的最后一行加入
export 变量=值
- 运行
source /etc/profile
或. /etc/profile
让此配置文件生效 - 目的达到
- 在/etc/profile文件的最后一行加入
- 仅允许当前用户使用该变量。
- 在用户家目录下的.bashrc文件的最后一行加入
export 变量=值
- 运行
source .bashrc
或. .bashrc
让配置文件生效 - 目的达到
- 在用户家目录下的.bashrc文件的最后一行加入
变量的配置文件
这些配置文件总结如下表:
配置文件名 | 文件的作用 |
---|---|
/etc/profile | 到交互登陆时才执行。这个文件预设了几个重要的变量,例如PATH、USER、LOGNAME、MAIL、INPUTRC、HOSTNAME、HISTSIZE、umask等 |
/etc/bashrc | 用户不用登陆,执行shell就生效。这个文件主要预设umask以及PS1 |
.bash_profile | 该文件定义了用户的个人化路径与环境变量的文件名称。每个用户都可以使用该文件输入专属于自己的shell信息,当用户登陆时,该文件仅仅执行一次 |
.bashrc | 该文件包含专属于自己的shell的bash信息,当登陆或每次打开新的shell时,该文件会被读取。例如,用户可以将自己定义的别名或者自定义变量写到这个文件中 |
.bash_history | 该文件用于记录命令历史 |
.bash_logout | 当退出shell时,会执行该文件。可以将一些清理的工作放到这个文件中 |
PS1变量的说明
这个PS1就是我们在输入命令时前面的那串字符。如 [root@AmingLinux-105 ~]#
,我们来查看一下PS1的值:
其中,\u是用户名,\h是主机名,\W当前目录名,(\w表示的是工作目录的完整绝对路径),\$代表用户身份字符(root为#,普通用户为$)
Shell 中的特殊符号
特殊符号
特殊符号 | 意义 |
---|---|
* | 代表零个或多个任意字符 |
? | 只代表一个任意字符 |
# | 注释符,这个符号在Linux中表示注释说明,在后面的内容都会被忽略 |
\ | 脱义字符,将后面的特殊字符还原为普通字符 |
管道符 | 将前面命令的输出作为后面命令的输入。支持它的工具有cat、less、head、tail、grep、cut、sort、wc、uniq、tee、tr、split、sed、awk等 |
$变量名 | 它可以作为变量前面的标识符 |
$? | 表示上一条的命令执行的返回值,若为0则正确执行,若非零则错误执行 |
!$ | 表示上条命令中的最后一个变量 |
; | 如果在多条命令中间使用这个符号连接,则表示按顺序依次执行 |
~ | 代表用户的家目录,用于cd ~ |
& | 表示把命令放到后台执行,用于命令 & ;&&代表逻辑与;&1代表参数1 |
重定向 | >、>>、2>、2>>、< |
中括号[] | 中括号内为字符组合中的任意一个,可以是一个范围([1-3a-z]) |
还有两个符号&&和||,将与;放在一起进行总结:
command1 ; command2
不管command1是否执行成功,都会执行command2command1 && command2
只有command1执行成功后,才会执行command2command1 || command2
只有command1执行失败了,才会执行command2
几个常用的管道命令
cut
cut 用来截取某一个字段。
格式 cut -d '分隔字符' [-cf] n
,这里n是数字。其选项说明如下:
选项 | 说明 |
---|---|
-d | 后面跟分隔字符,分隔字符要用单引号括起来 |
-c | 后面接的是第几个字符 |
-f | 后面接的是第几个区块 |
cut命令的用法说明:
-d选项后面加冒号作为分隔字符,-f 1 表示截取第一段,-f和1之间的空格可有可无。示例如下:
cut -d ‘分隔符’ -f 1 filename
cut -d ‘分隔符’ -f 1,2 filename
cut -d ‘分隔符’ -f 1-4 filename
123456[root@AmingLinux-105 ~]rootbindaemonadmlp
-c选项后面可以一个数字n,也可以是一个区间n1-n2,还可以是多个数字n1,n2,n3。示例如下:
123456789101112[root@AmingLinux-105 ~]# head -n2 /etc/passwd | cut -c2oi[root@AmingLinux-105 ~]# head -n2 /etc/passwd | cut -c1rb[root@AmingLinux-105 ~]# head -n2 /etc/passwd | cut -c1-10root:x:0:0bin:x:1:1:[root@AmingLinux-105 ~]# head -n2 /etc/passwd | cut -c1,3,10ro0bn:
sort
sort 用作排序
格式 sort [-t 分隔符] [-kn1,n2] [-nru]
,这里的n1和n2指的是数字,其它选项的含义如下
选项 | 含义 |
---|---|
-t | 后面跟分隔字符,作用跟cut的-d选项一样 |
-n | 表示使用纯数字排序 |
-r | 表示反向排序 |
-u | 表示去重复 |
-kn1,n2 | 表示由n1区间排序到n2区间,可以只写-kn1,表示只对n1字段排序 |
sort 命令的用法示例:
sort 如果不加任何选项,则从首字符向后依次按ASCII码值进行比较,最后将它们按升序输出。
123456[root@AmingLinux-105 ~]# head -n5 /etc/passwd | sortadm:x:3:4:adm:/var/adm:/sbin/nologinbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinlp:x:4:7:lp:/var/spool/lpd:/sbin/nologinroot:x:0:0:root:/root:/bin/bash-t 选项后面跟分隔符,-k 选项后面跟单个数字表示对第几个区域的字符串排序,-n选项则表示用纯数字排序。
123456[root@AmingLinux-105 ~]# head -n5 /etc/passwd | sort -t: -k3 -nroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin-k 选项后面跟数字n1和n2表示对第n1和n2区域内的字符串排序,-r选项则表示反向排序。
1234567[root@AmingLinux-105 ~]# head -n5 /etc/passwd | sort -t: -k3,5 -rlp:x:4:7:lp:/var/spool/lpd:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinbin:x:1:1:bin:/bin:/sbin/nologinroot:x:0:0:root:/root:/bin/bash//这里的-k3,5表示对第3区域至第5区域间的字符串排序。
wc
wc 用于统计文档的行数、字符数或词数。
常用选项 | 含义 |
---|---|
不加选项 | 依次输出文档的行数、词数和字符数 |
-l | 统计行数 |
-m | 统计字符数 |
-w | 统计词数 |
示例命令如下:
uniq
uniq 用来删除重复的行
该命令只有-c选项最常用,它表示统计重复的行数,并把行数写在最前面。使用uniq前,必须先给文件排序,否则不管用。示例如下:
tee
tee 命令类似于重定向>,它的作用是既输出到文件,又输出到屏幕,可以叫它为”双向重定向”。
tee 命令后面跟文件名,且它常用与管道符后面。示例如下:
tr
tr 用于替换字符,常用来处理文档中出现的特殊符号,如DOS文档中出现的^M。这个工具是针对一个字符来讲的,有一定的局限性。
常用选项 | 含义 |
---|---|
-d | 表示删除某个字符,后面跟要删除的字符 |
-s | 表示删除重复的字符 |
示例如下:
tr 常用于把小写字母变成大写字母,如
tr '[a-z]' '[A-Z]'
。123[root@AmingLinux-105 test]# head -n2 /etc/passwd | tr '[a-z]' '[A-Z]'ROOT:X:0:0:ROOT:/ROOT:/BIN/BASHBIN:X:1:1:BIN:/BIN:/SBIN/NOLOGINtr 还可以替换一个字符。
123[root@AmingLinux-105 test]# grep 'root' /etc/passwd | tr 'r' 'R'Root:x:0:0:Root:/Root:/bin/bashopeRatoR:x:11:0:opeRatoR:/Root:/sbin/nologin
split
split 用于切割文档,常用选项为-b和-l
常用选项 | 含义 |
---|---|
-b | 依据大小来分割文档,单位为byte |
-l | 依据行数来分割文档 |
示例如下:
如果split不指定目标文件名,则会以xaa、xab、xac….这样的文件名来存储切割后的文件。当然,也可以指定目标文件名。示例如下:
使用-l选项的示例:
OK